package org.blxt.maven;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 * Java文件代码行分析器
 */
public class JavaFileAnalyzer {
    
    /**
     * 文件分析结果
     */
    public static class FileStats {
        private final int totalLines;
        private final int commentLines;
        private final int codeLines;
        private final int blankLines;
        
        public FileStats(int totalLines, int commentLines, int codeLines, int blankLines) {
            this.totalLines = totalLines;
            this.commentLines = commentLines;
            this.codeLines = codeLines;
            this.blankLines = blankLines;
        }
        
        public int getTotalLines() { return totalLines; }
        public int getCommentLines() { return commentLines; }
        public int getCodeLines() { return codeLines; }
        public int getBlankLines() { return blankLines; }
    }
    
    /**
     * 分析Java文件
     */
    public FileStats analyzeFile(File file) throws IOException {
        return analyzeFile(file, true, true);
    }
    
    /**
     * 分析Java文件
     * @param file 要分析的文件
     * @param includeImportLines 是否将import行计入代码行统计
     * @param includeBlankLines 是否将空白行计入统计
     */
    public FileStats analyzeFile(File file, boolean includeImportLines, boolean includeBlankLines) throws IOException {
        int totalLines = 0;
        int commentLines = 0;
        int codeLines = 0;
        int blankLines = 0;
        
        boolean inBlockComment = false;
        boolean packageFound = false;
        boolean inFileHeaderComment = false;
        
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = reader.readLine()) != null) {
                totalLines++;
                String trimmedLine = line.trim();
                
                // 检查是否到达package声明
                if (!packageFound && trimmedLine.startsWith("package ")) {
                    packageFound = true;
                    inFileHeaderComment = false;
                    codeLines++;
                    continue;
                }
                
                if (trimmedLine.isEmpty()) {
                    if (includeBlankLines) {
                        blankLines++;
                    }
                    continue;
                }
                
                // 如果还没找到package声明，检查是否是文件头注释
                if (!packageFound) {
                    if (trimmedLine.startsWith("/*") || trimmedLine.startsWith("//") || 
                        trimmedLine.startsWith("*") || inFileHeaderComment) {
                        // 这是文件头注释，不计入注释统计
                        if (trimmedLine.startsWith("/*")) {
                            inFileHeaderComment = true;
                        }
                        if (trimmedLine.contains("*/")) {
                            inFileHeaderComment = false;
                        }
                        continue;
                    }
                    // 如果不是注释也不是package，可能是import或其他代码
                    if (trimmedLine.startsWith("import ")) {
                        packageFound = true;
                        if (includeImportLines) {
                            codeLines++;
                        }
                        continue;
                    } else if (trimmedLine.startsWith("@") ||
                        trimmedLine.startsWith("public ") ||
                        trimmedLine.startsWith("private ") ||
                        trimmedLine.startsWith("protected ") ||
                        trimmedLine.startsWith("class ") ||
                        trimmedLine.startsWith("interface ") ||
                        trimmedLine.startsWith("enum ")) {
                        // 这些也算代码开始了
                        packageFound = true;
                        codeLines++;
                        continue;
                    }
                }
                
                // package声明之后的正常分析逻辑
                boolean isCommentLine = false;
                
                // 检查块注释的开始和结束
                if (inBlockComment) {
                    isCommentLine = true;
                    if (trimmedLine.contains("*/")) {
                        inBlockComment = false;
                        // 检查 */ 后面是否还有代码
                        String afterComment = trimmedLine.substring(trimmedLine.indexOf("*/") + 2).trim();
                        if (!afterComment.isEmpty()) {
                            // */ 后面还有代码，这行既是注释行也是代码行，但我们归类为代码行
                            isCommentLine = false;
                            codeLines++;
                        } else {
                            commentLines++;
                        }
                    } else {
                        commentLines++;
                    }
                } else {
                    // 不在块注释中
                    if (trimmedLine.startsWith("//")) {
                        // 单行注释
                        isCommentLine = true;
                        commentLines++;
                    } else if (trimmedLine.startsWith("/*")) {
                        // 块注释开始
                        isCommentLine = true;
                        if (trimmedLine.contains("*/")) {
                            // 单行块注释
                            String afterComment = trimmedLine.substring(trimmedLine.indexOf("*/") + 2).trim();
                            if (!afterComment.isEmpty()) {
                                // 注释后面还有代码
                                isCommentLine = false;
                                codeLines++;
                            } else {
                                commentLines++;
                            }
                        } else {
                            // 多行块注释开始
                            inBlockComment = true;
                            commentLines++;
                        }
                    } else if (trimmedLine.contains("//")) {
                        // 行中包含注释，但不以注释开头，归类为代码行
                        codeLines++;
                    } else if (trimmedLine.contains("/*")) {
                        // 行中包含块注释开始
                        if (trimmedLine.contains("*/")) {
                            // 行中的完整块注释，归类为代码行
                            codeLines++;
                        } else {
                            // 行中开始块注释，归类为代码行
                            inBlockComment = true;
                            codeLines++;
                        }
                    } else if (trimmedLine.startsWith("import ")) {
                        // import语句的处理
                        if (includeImportLines) {
                            codeLines++;
                        }
                    } else {
                        // 普通代码行
                        codeLines++;
                    }
                }
            }
        }
        
        return new FileStats(totalLines, commentLines, codeLines, blankLines);
    }
}